package com.hup.utils.commons.start;

import java.util.HashMap;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * 不依赖于Spring的bean管理类
 *
 * @author hugan
 * @date 2021/5/24
 */
public class ApplicationContext {
    private HashMap<Class<?>, Object> mapBean;

    public ApplicationContext() {
        this.mapBean = new HashMap<>();
    }

    public <T> T putBean(T bean) {
        mapBean.put(bean.getClass(), bean);
        return bean;
    }

    public <T> T putBean(Class<T> clz, T bean) {
        mapBean.put(clz, bean);
        return bean;
    }

    public void removeBean(Class<?> clz) {
        mapBean.remove(clz);
    }

    @SuppressWarnings("unchecked")
    public <T> T getBean(Class<T> clz) {
        T res = (T) mapBean.get(clz);
        if (res == null) throw new IllegalArgumentException("找不到bean:" + clz.getName());
        return res;
    }

    @SuppressWarnings("unchecked")
    public <T> T getBeanNullable(Class<T> clz) {
        return (T) mapBean.get(clz);
    }

    /**
     * @return hadExe
     */
    @SuppressWarnings("unchecked")
    public <T> boolean executeIfExist(Class<T> clz, Consumer<T> consumer) {
        T bean = (T) mapBean.get(clz);
        if (bean != null) {
            consumer.accept(bean);
            return true;
        } else {
            return false;
        }
    }

    @SuppressWarnings("unchecked")
    public <T, I, O> O executeIfExist(Class<T> clz, I param, Function<I, O> function) {
        T bean = (T) mapBean.get(clz);
        if (bean == null) return null;
        return function.apply(param);
    }

    /**
     * @return hadExe
     */
    @SuppressWarnings("unchecked")
    public <T> boolean executeForeach(Class<? extends List<T>> clz, Consumer<T> consumer) {
        List<T> list = (List<T>) mapBean.get(clz);
        boolean hadExe = false;
        if (list != null) {
            for (T item : list) {
                consumer.accept(item);
                hadExe = true;
            }
        }
        return hadExe;
    }
}
